package ru.ifmo.ct.network.brafs.node;

import ru.ifmo.ct.network.brafs.file.FileHolder;
import ru.ifmo.ct.network.brafs.file.HDDFileHolder;
import ru.ifmo.ct.network.brafs.file.InMemoryFileHolder;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Scanner;

/**
 * @author Alex Vikharev vikharev@yandex-team.ru
 *         created 18.04.12
 */
public class BraNode {
    public static final int DEFAULT_PORT = 11461;

    public static void main(String[] args) throws IOException {
        int port = DEFAULT_PORT;
        try {
            port = Integer.parseInt(args[0]);
        } catch (Exception ignored) {
        }

        String serverAddr = args[1];
        int serverPort = DEFAULT_PORT;
        try {
            serverPort = Integer.parseInt(args[2]);
        } catch (Exception ignored) {
        }

        sendGreeting(serverAddr, serverPort, port);
        System.err.println("Greeting send successfully");

        final ServerSocket server = new ServerSocket(port);
        final Thread thread = Thread.currentThread();

        FileHolder fileHolder = new HDDFileHolder();

        new Thread() {
            @Override
            public void run() {
                final Scanner s = new Scanner(System.in);
                while (s.hasNext()) {
                    if (s.next().equalsIgnoreCase("exit")) {
                        break;
                    }
                }
                thread.interrupt();
            }
        }.start();

        server.setSoTimeout(500);

        while (!Thread.interrupted()) {
            try {
                final Socket client = server.accept();
                new Thread(new CommandDispatcher(fileHolder, client)).start();
            } catch (SocketTimeoutException ignored) {
            }
        }
        server.close();
    }

    private static void sendGreeting(final String ip, final int port, final int incomingPort) throws IOException {
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(ip, port));
            final Command command = new Command(CommandType.HELLO, new byte[4], incomingPort, 0L, "");
            command.write(socket.getOutputStream());
        }
    }


}
